const htmlparser2 = require('htmlparser2');
export const htmlToAST = (html, depth) => {
  let ast = {};
  let curEl = ast;
  let parser = new htmlparser2.Parser(
    {
      onopentag(name, attribs) {
        attribs = Object.keys(attribs).reduce((prev, next) => {
          if(attribs[next] && 'class' === next) {
            prev['className'] = attribs[next];
          }
          else {
            prev[next] = attribs[next];
          }
          return prev;
        }, {});
        curEl = makAst(curEl, name, attribs);
      },
      ontext(text) {
        let str = text.replace(/\n/g, '').trim();
        if(str === "") {
          return;
        }
        while(curEl && curEl.closed) {
          curEl = curEl.parent;
        }
        if(! curEl) {return;}
        curEl.children.push(str);
      },
      onclosetag(tagname) {
        while(curEl.closed) {
          curEl = curEl.parent;
        }
        curEl && (curEl.closed = true);
      }
    },
    { decodeEntities: true }
  );
  parser.write(html);
  parser.end();
  // console.log(ast);
  return ast;
}

const makAst = (ast, name, attribs) => {
  // 当前标签
  if(! ast.name) {
    ast.name = name;
    ast.attribs = attribs;
    ast.children = [];
    ast.closed = false;
    return ast;
  }
  // 当前标签没有关闭，说明有子节点
  else if(! ast.closed) {
    let curEl = {
      name, attribs,
      children: [],
      parent: ast,
      closed: false
    };
    ast.children.push(curEl);
    return curEl;
  }
  // 当前标签已关闭，需要进行下一个节点的处理
  else {
    while(ast.closed) {
      ast = ast.parent;
    }
    return makAst(ast, name, attribs);
  }
}

export const astToHtml = (ast) => {
  if(! ast) {
    return "";
  }
  let html = `<${ ast.name }${ addAttribs(ast.attribs) }>${ ast.children.map(child => typeof child === 'string'? child: `
  ${astToHtml(child)}
` ).reduce((prev, next) => prev + next, '') }</${ ast.name }>`;
  return html;
}

const addAttribs = (attr) => {
  return Object.keys(attr).reduce((prev, next) => {
    if(next === 'className') {
      return prev + ' class="' + attr[next] + '"';
    }
    return prev + ' ' + next + '="' + attr[next] + '"';
  }, '');
}